Crypto
Must be included via require.
Non-Cryptographic Hashing Algorithms
crypto.lua
Hash a string using Lua's version of the DJB2 non-cryptographic hashing algorithm.
Parameters
- The string to hash.
plutolocal crypto = require("crypto")local str = "hello world"print(crypto.lua(str)) --> 2871868277
crypto.djb2
Hash a string using the DJB2 non-cryptographic hashing algorithm.
Parameters
- The string to hash.
Returns
An integer between 0 and 0xffffffff, inclusive.
plutolocal crypto = require("crypto")local str = "hello world"print(crypto.djb2(str)) --> 894552257
crypto.fnv1
Hash a string using the 64-bit FNV1 non-cryptographic hashing algorithm.
Parameters
- The string to hash.
plutolocal crypto = require("crypto")local str = "hello world"print(crypto.fnv1(str)) --> 9065573210506989167
crypto.fnv1a
Hash a string using the 64-bit FNV1A non-cryptographic hashing algorithm.
Parameters
- The string to hash.
plutolocal crypto = require("crypto")local str = "hello world"print(crypto.fnv1a(str)) --> 8618312879776256743
crypto.fnv1a32
Hash a string using the 32-bit FNV1A non-cryptographic hashing algorithm.
Parameters
- The string to hash.
plutolocal crypto = require("crypto")local str = "hello world"print(crypto.fnv1a32(str)) --> 3582672807
crypto.joaat
Hash a string using the JOAAT non-cryptographic hashing algorithm.
Parameters
- The string to hash.
Returns
An integer between 0 and 0xffffffff, inclusive.
plutolocal crypto = require("crypto")local str = "hello world"print(crypto.joaat(str)) --> 1045060183
crypto.sdbm
Hash a string using the SDBM non-cryptographic hashing algorithm.
Parameters
- The string to hash.
Returns
An integer between 0 and 0xffffffff, inclusive.
plutolocal crypto = require("crypto")local str = "hello world"print(crypto.sdbm(str)) --> 430867652
crypto.crc32
Hash a string using the CRC32 non-cryptographic hashing algorithm.
Parameters
- The string to hash.
- The initial value for the hash. By default, this is zero.
Returns
An integer between 0 and 0xffffffff, inclusive.
plutolocal crypto = require("crypto")local str = "hello world"print(crypto.crc32(str)) --> 222957957
crypto.crc32c
Hash a string using the CRC32C non-cryptographic hashing algorithm.
Parameters
- The string to hash.
- The initial value for the hash. By default, this is zero.
Returns
An integer between 0 and 0xffffffff, inclusive.
plutolocal crypto = require("crypto")local str = "hello world"print(crypto.crc32c(str)) --> 3381945770
crypto.adler32
Hash a string using the Adler-32 non-cryptographic hashing algorithm.
Parameters
- The string to hash.
- The initial value for the hash. By default, this is zero.
plutolocal crypto = require("crypto")local str = "hello"print(crypto.adler32(str)) --> 103547413
crypto.lookup3
Hash a string using the Lookup3 non-cryptographic hashing algorithm.
Parameters
- The string to hash.
plutolocal crypto = require("crypto")local str = "hello world"print(crypto.lookup3(str)) --> 1252609637
crypto.times33
Hash a string using the Times33 non-cryptographic hashing algorithm.
Parameters
- The string to hash.
Returns
An integer between 0 and 0xffffffff, inclusive.
plutolocal crypto = require("crypto")local str = "hello world"print(crypto.times33(str)) --> 3889643616
crypto.murmur1
Hash a string using the Murmur1 non-cryptographic hashing algorithm.
Parameters
- The string to hash.
Returns
An integer between 0 and 0xffffffff, inclusive.
plutolocal crypto = require("crypto")local str = "hello world"print(crypto.murmur1(str)) --> 3154674178
crypto.murmur2
Hash a string using the Murmur2 non-cryptographic hashing algorithm.
Parameters
- The string to hash.
Returns
An integer between 0 and 0xffffffff, inclusive.
plutolocal crypto = require("crypto")local str = "hello world"print(crypto.murmur2(str)) --> 1151865881
crypto.murmur2a
Hash a string using the Murmur2A non-cryptographic hashing algorithm.
Parameters
- The string to hash.
Returns
An integer between 0 and 0xffffffff, inclusive.
plutolocal crypto = require("crypto")local str = "hello world"print(crypto.murmur2a(str)) --> 2650573207
crypto.murmur64a
Hash a string using the Murmur64A non-cryptographic hashing algorithm.
Parameters
- The string to hash.
plutolocal crypto = require("crypto")local str = "hello world"print(crypto.murmur64a(str)) --> -3190198453633110066
crypto.murmur64b
Hash a string using the Murmur64A non-cryptographic hashing algorithm.
Parameters
- The string to hash.
plutolocal crypto = require("crypto")local str = "hello world"print(crypto.murmur64b(str)) --> 7088720765356542432
crypto.murmur2neutral
Hash a string using the Murmur2Neutral non-cryptographic hashing algorithm.
Parameters
- The string to hash.
plutolocal crypto = require("crypto")local str = "hello world"print(crypto.murmur2neutral(str)) --> 1151865881
Semi-Cryptographic Hashing Algorithms
crypto.md5
Hash a string using the MD5 semi-cryptographic hashing algorithm.
Parameters
- The string to hash.
- When set to true, returns raw binary data. false outputs lowercase hex digits. By default, this is false.
plutolocal crypto = require("crypto")local str = "hello world"print(crypto.md5(str)) --> 5eb63bbbe01eeed093cb22bb8f5acdc3print(crypto.md5(str, true)) --> \x5e\xb6\x3b\xbb\xe0\x1e\xee\xd0\x93\xcb\x22\xbb\x8f\x5a\xcd\xc3
Cryptographic Hashing Algorithms
crypto.sha1
Hash a string using the SHA-1 cryptographic hashing algorithm.
Parameters
- The string to hash.
- When set to true, returns raw binary data. false outputs lowercase hex digits. By default, this is false.
plutolocal crypto = require("crypto")print(crypto.sha1("Pluto")) --> bce8c9aca4120776fad6b517874aa09c46405454print(crypto.sha1("Pluto", true)) --> \xbc\xe8\xc9\xac\xa4\x12\x07\x76\xfa\xd6\xb5\x17\x87\x4a\xa0\x9c\x46\x40\x54\x54
crypto.sha256
Hash a string using the SHA-256 cryptographic hashing algorithm.
Parameters
- The string to hash.
- When set to true, returns raw binary data. false outputs lowercase hex digits. By default, this is false.
plutolocal crypto = require("crypto")print(crypto.sha256("Pluto")) --> 8dad5f6a7dd2dcd8c35ec2fd7babb499bcad60d27d73fe73eca2ce025dfd3b47print(crypto.sha256("Pluto", true)) --> \x8d\xad\x5f\x6a\x7d\xd2\xdc\xd8\xc3\x5e\xc2\xfd\x7b\xab\xb4\x99\xbc\xad\x60\xd2\x7d\x73\xfe\x73\xec\xa2\xce\x02\x5d\xfd\x3b\x47
crypto.sha384
Hash a string using the SHA-384 cryptographic hashing algorithm.
Parameters
- The string to hash.
- When set to true, returns raw binary data. false outputs lowercase hex digits. By default, this is false.
plutolocal crypto = require("crypto")print(crypto.sha384("Pluto", false)) --> db890233a919b6745d632633c419e14540ff79f1a89bc4ac194b00e7f913f0f06d5d4d7d6cc2b4aaf9485d223afb8cf0
crypto.sha512
Hash a string using the SHA-512 cryptographic hashing algorithm.
Parameters
- The string to hash.
- When set to true, returns raw binary data. false outputs lowercase hex digits. By default, this is false.
plutolocal crypto = require("crypto")print(crypto.sha512("Pluto", false)) --> ee8410a8bf9511b94fd6669b5c3e0c4b86e8e4bf7baa8dbd2773d4d6381dd1aecebbe391bef4c6158620ab3f6b794907652d4432c2301d7e1a6caf520565cdf2
crypto.ripemd160
Hash a string using the RIPEMD-160 cryptographic hashing algorithm.
Parameters
- The string to hash.
- When set to true, returns raw binary data. false outputs lowercase hex digits. By default, this is false.
plutolocal crypto = require("crypto")print(crypto.ripemd160("Pluto")) --> c2072a85f4a691803b8942709036072086fd9550
crypto.hmac
Authenticates a message using the HMAC construction with the given hash algorithm.
Parameters
- The hash algorithm to use.
"sha1","sha256","sha384", or"sha512". - The secret key.
- The message to authenticate.
- When set to true, returns raw binary data. false outputs lowercase hex digits. By default, this is false.
plutolocal crypto = require("crypto")local key = "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"aprint(crypto.hmac("sha256", key, "Hi There")) --> b0344c61d8db38535ca8afceaf0bf12b881dc200c9833da726e9376c2e32cff7
Cryptographic PRNGs
crypto.random
This is a cryptographically secure PRNG, assuming the platform's implementation of the underlying primitive is secure.
Parameters
This function takes 0-2 integer parameters that define the output range:
- If no arguments are given, an inclusive range from
math.minintegertomath.maxintegeris used. - If 1 argument (
n) is given, an inclusive range from 1 tonis used. - If 2 arguments (
l,u) are given, an inclusive range fromltouis used.
Returns
A random lua integer, in the given range.
plutolocal crypto = require("crypto")print(crypto.random()) -- Prints an integer from math.mininteger to math.maxinteger.print(crypto.random(6)) -- Prints an integer from 1 to 6, like a dice roll.print(crypto.random(10, 20)) -- Prints an integer from 10 to 20.
AES-CBC, AES-CFB
These unauthenticated AES modes take both a key and an IV. The IV must be unique and unpredictable for each encryption session to ensure security.
crypto.encrypt
Parameters
data— The data to be encrypted.mode— "aes-cbc-pkcs7" or "aes-cfb-pkcs7" for PKCS#7 padding, or "aes-cbc" or "aes-cfb" if you know what you're doing.key— Must have a length of 16, 24 or 32 for 128-, 192-, or 256-bit AES, respectively.iv— Must have a length of 16.
crypto.decrypt
Parameters
data— The ciphertext to decrypt.mode— "aes-cbc-pkcs7" or "aes-cfb-pkcs7" for PKCS#7 padding, or "aes-cbc" or "aes-cfb" if you know what you're doing.key— Must have a length of 16, 24 or 32 for 128-, 192-, or 256-bit AES, respectively.iv— Must have a length of 16.
Returns the decrypted data on success. Throws an error if the padding was incorrect.
plutolocal crypto = require "pluto:crypto"local key <const> = "A Top Secret Key"-- Encryptlocal iv = range(16):map(|| -> string.char(math.random(0, 255))):concat("")local plain = "Hello, world!"local enc = plain |> crypto.encrypt|"aes-cbc-pkcs7", key, iv|print(dumpvar(enc))-- Decryptprint(crypto.decrypt(enc, "aes-cbc-pkcs7", key, iv)) --> Hello, world!
AES-ECB
This unauthenticated AES mode takes only a key, and is considered to be the weakest. Identical plaintext blocks result in identical ciphertext blocks.
crypto.encrypt
Parameters
data— The data to be encrypted.mode— "aes-ecb-pkcs7" for PKCS#7 padding, or "aes-ecb" if you know what you're doing.key— Must have a length of 16, 24 or 32 for 128-, 192-, or 256-bit AES, respectively.
crypto.decrypt
Parameters
mode— "aes-ecb-pkcs7" for PKCS#7 padding, or "aes-ecb" if you know what you're doing.data— The ciphertext to decrypt.key— Must have a length of 16, 24 or 32 for 128-, 192-, or 256-bit AES, respectively.
Returns the decrypted data on success. Throws an error if the padding was incorrect.
plutolocal crypto = require "pluto:crypto"local key <const> = "A Top Secret Key"-- Encryptlocal plain = "Hello, world!"local enc = plain |> crypto.encrypt|"aes-ecb-pkcs7", key|print(dumpvar(enc)) --> string(16) "`p{����k\21*.>jG"-- Decryptprint(crypto.decrypt(enc, "aes-ecb-pkcs7", key)) --> Hello, world!
AES-GCM
This authenticated AES mode allows for additional data that will be validated although not encrypted, such as a Message Authentication Code (MAC).
crypto.encrypt
Parameters
data— The data to be encrypted.mode— Must be "aes-gcm". AES-GCM can deal with unpadded data, hence does not need PKCS#7 padding.aadata— Authenticated data. Will not be encrypted.key— Must have a length of 16, 24 or 32 for 128-, 192-, or 256-bit AES, respectively.iv— Must have a length of 16.
Returns two strings: the ciphertext and the authentication tag.
crypto.decrypt
Parameters
data— The ciphertext to decrypt.mode— Must be "aes-gcm".aadata— Authenticated data.key— Must have a length of 16, 24 or 32 for 128-, 192-, or 256-bit AES, respectively.iv— Must have a length of 16.tag— The authentication tag produced by the "encrypt" procedure.
Returns the decrypted data on success. Throws an error if authentication or unpadding failed.
plutolocal crypto = require "pluto:crypto"local key <const> = "A Top Secret Key"local aadata = "This is Pluto!"-- Encryptlocal iv = range(16):map(|| -> string.char(math.random(0, 255))):concat("")local plain = "Hello, world!"local enc, tag = plain |> crypto.encrypt|"aes-gcm", aadata, key, iv|print(dumpvar(enc))print(dumpvar(tag))-- Decryptprint(crypto.decrypt(enc, "aes-gcm", aadata, key, iv, tag)) --> Hello, world!
RSA
crypto.generatekeypair
Parameters
mode— Must be "rsa".bits— A positive integer for a strict bit-length requirement, or a negative integer for a lax requirement. Common values are1024,2048, and4096.
Returns two tables: The public key (consisting of n and e), and the private key (consisting of p and q). The Bigint class is used for all values.
plutolocal pub, priv = crypto.generatekeypair("rsa", 512)print(dumpvar(pub))--> {--> ["n"] = 11355630182234424425429331560518598643298965915936825610957270519615363349759012613228119611304846673085167794661819394470107090216347491908311079792054357,--> ["e"] = 65537,--> }print(dumpvar(priv))--> {--> ["p"] = 115443384115231951475820445136871322101870729500298182134363293112660251666017,--> ["q"] = 98365361248415863235179644468056200977592391948608651522703704315152579004021,--> }
crypto.derive
Derives a public key from a private key.
Parameters
mode— Must be "rsa".key— The private key containingpandq.
Returns
The public key corresponding to the private key.
plutolocal { bigint, crypto } = require "pluto:*"local priv = {p = new bigint("115443384115231951475820445136871322101870729500298182134363293112660251666017"),q = new bigint("98365361248415863235179644468056200977592391948608651522703704315152579004021"),}local pub = crypto.derive("rsa", priv)print(pub.n) --> 11355630182234424425429331560518598643298965915936825610957270519615363349759012613228119611304846673085167794661819394470107090216347491908311079792054357print(pub.e) --> 65537
crypto.exportkey
Exports a private key.
Parameters
- The key to export.
- The exchange format to use. Only "pem" is supported right now.
plutolocal { bigint, crypto } = require "pluto:*"local priv = {p = new bigint("115443384115231951475820445136871322101870729500298182134363293112660251666017"),q = new bigint("98365361248415863235179644468056200977592391948608651522703704315152579004021"),}print(crypto.exportkey(priv, "pem"))
-----BEGIN RSA PRIVATE KEY-----MIIBOwIBAAJBANjRKgOuLxSxbL/fFg/3rJeRGGKz0EjxjjuV6QmgjZGq1LpI2KH+TrxVV4L94U0TCFo19vYtV6T4bOH/MlA6kFUCAwEAAQJANcTrfzWpgd99WXkM6uFQiVcHneS7fPeAvziubf+F1E98zwFgLbIOiPSJcVkXc79A2PQZdbGq7dFAxVD0EpIsoQIhAP86o9Ap9KOH4rgZn8ElHyWKO/Cj8m7oHjSmHG/CBGZhAiEA2XjSTZJ37mg3gJOXlMjG4SK15/jRCB1CMx8f4VhBhnUCIQCWK0p3EDiAf1NGPs1gNxc8XzklPVFHMAuVrqbMmrs8AQIhAJ1aqvCuFlFO3zoNkRR64kxsjSq4AqfYY9oRn0OyVFcxAiBjueZ/sI52jgP8+xK2x7coiX5/tDmXCGlp5utUAjk2+Q==-----END RSA PRIVATE KEY-----
crypto.importkey
Imports a private key.
Parameters
- The encoded key.
- The exchange format to use. Only "pem" is supported right now.
plutolocal { bigint, crypto } = require "pluto:*"print(dumpvar(crypto.importkey([[-----BEGIN RSA PRIVATE KEY-----MIIBOwIBAAJBANjRKgOuLxSxbL/fFg/3rJeRGGKz0EjxjjuV6QmgjZGq1LpI2KH+TrxVV4L94U0TCFo19vYtV6T4bOH/MlA6kFUCAwEAAQJANcTrfzWpgd99WXkM6uFQiVcHneS7fPeAvziubf+F1E98zwFgLbIOiPSJcVkXc79A2PQZdbGq7dFAxVD0EpIsoQIhAP86o9Ap9KOH4rgZn8ElHyWKO/Cj8m7oHjSmHG/CBGZhAiEA2XjSTZJ37mg3gJOXlMjG4SK15/jRCB1CMx8f4VhBhnUCIQCWK0p3EDiAf1NGPs1gNxc8XzklPVFHMAuVrqbMmrs8AQIhAJ1aqvCuFlFO3zoNkRR64kxsjSq4AqfYY9oRn0OyVFcxAiBjueZ/sI52jgP8+xK2x7coiX5/tDmXCGlp5utUAjk2+Q==-----END RSA PRIVATE KEY-----]], "pem")))
{["p"] = 115443384115231951475820445136871322101870729500298182134363293112660251666017,["q"] = 98365361248415863235179644468056200977592391948608651522703704315152579004021,}
crypto.encrypt
Parameters
data— The data to be encrypted.mode— "rsa-sha1", "rsa-sha256", "rsa-sha384", or "rsa-sha512" for RSA-OAEP with the corresponding hash, "rsa-pkcs1" for PKCS#1 v1.5, or "rsa" if you know what you're doing.key— The public or private key to use. Commonly, a public key is used to encrypt data.label— (optional) Associated data/label used for RSA-OAEP. Must match between encryption and decryption.
crypto.decrypt
Parameters
data— The ciphertext to decrypt.mode— "rsa-sha1", "rsa-sha256", "rsa-sha384", or "rsa-sha512" for RSA-OAEP with the corresponding hash, "rsa-pkcs1" for PKCS#1 v1.5, or "rsa" if you know what you're doing.key— The public or private key to use. If the data was encrypted with the public key, the private key is needed to decrypt it.label— (optional) Associated data/label used for RSA-OAEP. Must match what was provided during encryption.
plutolocal { base64, bigint, crypto } = require "pluto:*"local priv = {p = new bigint("115443384115231951475820445136871322101870729500298182134363293112660251666017"),q = new bigint("98365361248415863235179644468056200977592391948608651522703704315152579004021"),}local pub = crypto.derive("rsa", priv)-- Encryptlocal enc = crypto.encrypt("You know the primes!", "rsa-sha1", pub, "Authenticated Data")print(base64.encode(enc))-- Decryptprint(enc |> crypto.decrypt|"rsa-sha1", priv, "Authenticated Data"|) --> You know the primes!
crypto.sign
Signs a message as per the PKCS#1 v1.5 scheme.
Parameters
data— The data to sign.mode— "rsa-sha256" or "rsa-sha1".key— The private key to use.
crypto.verify
Verifies a message as per the PKCS#1 v1.5 scheme.
Parameters
data— The data that was signed.mode— "rsa-sha256" or "rsa-sha1".key— The public key corresponding to the signer's private key.signature— The signature produced by the "sign" procedure.
Returns a boolean that indicates if the signature validated successfully.
plutolocal { base64, bigint, crypto } = require "pluto:*"local priv = {p = new bigint("115443384115231951475820445136871322101870729500298182134363293112660251666017"),q = new bigint("98365361248415863235179644468056200977592391948608651522703704315152579004021"),}-- Derive public keylocal pub = {n = priv.p * priv.q, -- 11355630182234424425429331560518598643298965915936825610957270519615363349759012613228119611304846673085167794661819394470107090216347491908311079792054357e = new bigint(0x10001) -- 65537}-- Signlocal msg = "The canary has left the nest."local sig = msg |> crypto.sign|"rsa-sha256", priv|print(base64.encode(sig)) --> un1g04+cwG8WxYDpSlj4PO/hsTqSITgYKycRuR+m3AE6ypLyUCrVHC/0j4M3DeW81ADZVda6TVkC/Ht8EdYeFw==-- Verifyprint(crypto.verify(msg, "rsa-sha256", pub, sig)) --> true
Curve25519
crypto.generatekeypair
Generates a keypair for Curve25519.
Parameters
mode— Must be "curve25519".
Returns two strings: the public key and the private key, each 32 bytes.
plutolocal crypto = require "pluto:crypto"local pub, priv = crypto.generatekeypair("curve25519")print(priv:tohex())print(pub:tohex())assert(crypto.derive("curve25519", priv) == pub)
crypto.derive
Derives a Curve25519 public key from a private key.
Parameters
mode— Must be "curve25519".key— The 32-byte private key.
Returns the corresponding public key.
crypto.x25519
Performs an X25519 Diffie-Hellman exchange on Curve25519.
Parameters
private— The local 32-byte private key.public— The peer's 32-byte public key.
Returns the 32-byte shared secret.
plutolocal crypto = require "pluto:crypto"local alice_priv <const> = "77076d0a7318a57d3c16c17251b26645df4c2f87ebc0992ab177fba51db92c2a":fromhex()local alice_pub <const> = "8520f0098930a754748b7ddcb43ef75a0dbf3a0d26381af4eba4a98eaa9b4e6a":fromhex()local bob_priv <const> = "5dab087e624a8a4b79e17f8b83800ee66f3bb1292618b6fd1c2f8b27ff88e0eb":fromhex()local bob_pub <const> = "de9edb7d7b7dc1b4d35b61c2ece435373f8343c85b78674dadfc7e146f882b4f":fromhex()print(crypto.x25519(alice_priv, bob_pub):tohex()) --> 4a5d9d5ba4ce2de1728e3bf480350f25e07e21c947d19e3376f09b3c1e161742print(crypto.x25519(bob_priv, alice_pub):tohex()) --> 4a5d9d5ba4ce2de1728e3bf480350f25e07e21c947d19e3376f09b3c1e161742
Miscellaneous
crypto.decompress
Decompresses a DEFLATE-compressed string (one might call this an "INFLATE" function). Compatible with gzip and zlib headers and footers.
Parameters
data— The string to decompress.offset— Optional starting position insidedata, usingstring.subsemantics. Defaults to the beginning ofdata. To provide anoffsetwithout a decompressed size, passnilas the third argument.decompressed_size— Optional size of the decompressed output. When only two arguments are given, the second argument is treated asdecompressed_size.
Returns
- The decompressed string.
- A table with extra information:
compressed_size,checksum_present,checksum_mismatch
plutolocal deflated = "\xF3\x48\xCD\xC9\xC9\xD7\x51\x08\xC8\x29\x2D\xC9\x57\x04"local decompressed, info = require"crypto".decompress(deflated)print(decompressed) --> Hello, Pluto!print(info.compressed_size) --> 14print(info.checksum_present) --> falseprint(info.checksum_mismatch) --> false-- Decompress from an offsetdecompressed, info = require"crypto".decompress("Don't mind me" .. deflated, 14, nil)print(decompressed) --> Hello, Plutoprint(info.compressed_size) --> 14